// 模拟实现:一个线程控制一批线程的操作
#include <iostream>
using namespace std;
#include <vector>
#include <string>
#include <pthread.h>
#include <unistd.h>

// 定义互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// 定义条件变量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

// 主线程执行方法
void *MasterCore(void *args)
{
    string name = static_cast<const char *>(args);
    while (true)
    {
        // 主控线程定时唤醒新线程
        // 唤醒条件变量队列下的首个线程
        pthread_cond_signal(&cond);
        // 唤醒条件变量队列下的所有线程
        // pthread_cond_broadcast(&cond);
        cout << "开始唤醒条件变量下的线程------" << endl;
        sleep(1);
    }
}

// 新线程执行方法
void *SlaverCore(void *args)
{
    string name = static_cast<const char *>(args);
    while (true)
    {
        // 加锁
        pthread_mutex_lock(&mutex);
        // 使线程在条件变量下等待
        pthread_cond_wait(&cond, &mutex); // 此mutex互斥锁是要被释放的
        // wait成功之后,被唤醒之后,cout
        cout << "线程-" << name << "被唤醒------" << endl;
        // 解锁
        pthread_mutex_unlock(&mutex);
    }
}

// 启动一个主控线程
void StartMaster(vector<pthread_t> *tidsptr)
{
    pthread_t tid;
    int n = pthread_create(&tid, nullptr, MasterCore, (void *)"Master Thread");
    if (n == 0)
    {
        // 申请主线程成功
        cout << "申请主控线程成功" << endl;
    }
    // 将主线程的tid管理起来
    tidsptr->emplace_back(tid);
}

// 创建一批(n个)新线程
void StartSlaver(vector<pthread_t> *tidsptr, int threadnum = 3)
{
    for (int i = 0; i < threadnum; i++)
    {
        // 给每个线程构建名称
        char *name = new char[64];
        snprintf(name, 64, "Slaver-%d", i + 1);
        // 创建线程
        pthread_t tid;
        int n = pthread_create(&tid, nullptr, SlaverCore, name);
        if (n == 0)
        {
            // 创建新线程成功
            cout << "创建新线程成功---name:" << name << endl;
            // 将创建的线程管理起来
            tidsptr->emplace_back(tid);
        }
    }
}
// 对所有线程进行等待
void WaitThread(vector<pthread_t> &tidsptr)
{
    for (int i = 0; i < tidsptr.size(); i++)
    {
        // 等待线程
        pthread_join(tidsptr[i], nullptr);
    }
}
int main()
{
    vector<pthread_t> tids;
    StartMaster(&tids);     // 启动主控线程
    StartSlaver(&tids, 10); // 启动一批新线程

    WaitThread(tids); // 等待回收线程
    return 0;
}